package yxy.game.pm2.bean.module;

import org.redisson.api.RBucket;
import org.redisson.api.RLock;
import yxy.apple.util.redisson.RedisConnection;
import yxy.apple.util.redisson.RedisException;
import yxy.cherry.game.base.redis.RedisManager;
import yxy.cherry.game.base.redis.RedisType;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

public abstract class BaseGameRedisLockBean {
	// redis==========================================================================

	static protected RedisConnection redis() {
		return RedisManager.getInstance().getConnection(RedisType.REDIS_GAME);
	}

	static protected <V> RBucket<V> touchBucket(String key) throws RedisException {
		return RedisManager.client(redis()).getBucket(key);
	}

	protected static <V extends BaseGameRedisLockBean> V getv(String key) throws RedisException {
		RBucket<V> bucket = touchBucket(key);
		return bucket.get();
	}

	protected static <V extends BaseGameRedisLockBean> void setv(String key, V m) throws RedisException {
		RBucket<V> bucket = touchBucket(key);
		bucket.set(m);
	}

	// lock==========================================================================

	static private ConcurrentHashMap<String, RLock> lockMap;

	static private RLock lock(String lockKey) {
		if (lockMap == null) {
			lockMap = new ConcurrentHashMap<>();
		}
		if (!lockMap.containsKey(lockKey)) {
			RLock lock = redis().client().getLock(lockKey);
			lockMap.put(lockKey, lock);
		}
		return lockMap.get(lockKey);
	}

	static public boolean tryLock(String lockKey) throws InterruptedException {
//		System.err.println("tryLock::	" + lockKey);
		RLock lock = lock(lockKey);
		if (lock.isLocked()) {
			return true;
		}
		return lock.tryLock(20, 10, TimeUnit.SECONDS);
	}

	static public void unlock(String lockKey) {
//		System.err.println("unlock::	" + lockKey);
		if (lockMap == null) {
			return;
		}
		if (!lockMap.containsKey(lockKey)) {
			return;
		}
		try {
			RLock lock = lockMap.remove(lockKey);
			lock.unlock();
		} catch (Exception e) {
		}
	}

	static public RLock getRedisLock(String lockKey)  {
		return redis().client().getLock(lockKey);
	}
}
